<?php
/* Copyright [2014] UW-Parkside
 * Authors: Matthew Zygowicz, Armando Narvaez
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

/**
 *This model controls the logic involved with manipulating users
 *and the users table.  Any operation involving a user should
 *be done in this class.
 */
class User extends CI_Model {

    var $username;
    var $password;
    var $PASSWORD_SALT = '22e244a1d446ae91a77200da7c82269d839f3b7714a94a73bea98fa502b5ace9';
    /**
     *Load the database from the config file, and register this function
     *as a valid codeigniter model
     */
    public function __construct() {
        $this->load->database();
        parent::__construct();
    }

    /**
     *this function creates a user given the parameters.
     *Password is hashed inside the function.
     *
     *@param string $username the username of the user
     *@param string $password the password of the user, in plaintext
     *@param string $realm the access level of the user
     */
    public function createUser($username, $password, $realm) {
	$this->load->model('realms');

	$hashedPass = hash('sha256', $this->PASSWORD_SALT . $password);
        $realmId = $this->realms->getRealmId($realm);
        $sql = "INSERT INTO userinfo (`vcUsername`,`vcPassword`, `iRealm`) VALUES (?,?,?)";
        $this->db->query($sql, array($username, $hashedPass, $realmId));
    }
    
    /**
     *This function changes a given users password.  Password is hashed inside
     *the function.
     *@param int $id the database iUID of the user.
     *@param string $username the username of the user
     *@param string $password the password of the user, in plaintext
     */ 
    public function changePassword($id, $username, $password) {
	$hashedPass = hash('sha256', $this->PASSWORD_SALT . $password);
        $sql = "UPDATE userinfo SET vcPassword=? WHERE iUid= ? AND vcUsername=?;";
        //FIXME
        $this->db->query($sql, array($hashedPass, $id, $username));
    }
    
    /**
     *This function changes a given users realm.
     *@param int $id the database iUID of the user.
     *@param string $username the username of the user
     *@param string $realm the new access level of the user
     *@return string returns an empty string on sucess
     *@return string reutrns an error message upon failure
     */ 
    public function editUser($id, $username, $realm){
        $realms = new Realms();
        $realmId = $realms->getRealmId($realm);
        if($this->doesUserExist($username)){
            $sql = "UPDATE userinfo SET iRealm=? WHERE iUid= ? AND vcUsername=?;";
            $this->db->query($sql, array($realmId, $id, $username));
            return "";
        }
        return "Cannot edit username or username not found!";

    }
    
    /**
     *This function logs a user in given valid credentials.
     *Password is passed in plaintext.  Upon success username and
     *realm are stored in the session
     *
     *@param string $username the username of the user
     *@param string $password the attempted password of the user, in plaintext
     *
     *@return string returns a string of length 0 and stores realm and user in session on sucess
     *@return string returns a string detailing the error message upon failure.
     */
    public function loginUser($username, $password) {
	$hashedPass = hash('sha256', $this->PASSWORD_SALT . $password);
        $sql = "SELECT vcUsername, vcPassword, vcRealm FROM userinfo  JOIN realms on userinfo.iRealm = realms.iRid WHERE vcUsername=? and vcPassword=?";
        $query = $this->db->query($sql, array($username,$hashedPass));
        if ($query->num_rows() > 0) {
            $result = $query->result_array();
            $_SESSION['realm'] = $result[0]['vcRealm'];
                $_SESSION['user'] = $result[0]['vcUsername'];
                return '';
        }
        return 'Invalid Username/Password!';
    }
	
    /**
     *This function deletes a given user given the username
     *
     *@param string $username the username of the user to be deleted
     */
    public function deleteUser($username){
	    $sql = "DELETE from userinfo WHERE vcUsername=?;";
	    $this->db->query($sql, array($username));
    
    }
	
    /**
     *This function updates a given user to the new given password
     *
     *@param string $username the username of the user to be affected.
     *@param string $password the new password of the user, in plain text.
     */
    public function updatePassword($username, $password){
        //$hashedPass = password_hash($password, PASSWORD_BCRYPT);
	$hashedPass = hash('sha256', $this->PASSWORD_SALT . $password);
        $sql = "UPDATE userinfo SET password=? WHERE username=?;";
        $this->db->query($sql, array($username, $hashedPass));
    }
    
    /**
     *This function destroys the session to force the logout of the user
     */
    public function logout() {
	$_SESSION['user'] = '';
	unset($_SESSION['user']);
        session_destroy();
    }
        
    /**
     *This function checks to see if a given username already exists in the database
     *
     *@param string username the username to check if it exists
     *@return true if the user exists
     *@return false if the user does not exist
     */
    public function doesUserExist($username) {
        /* Create a prepared statement */
        $sql = "SELECT vcUsername FROM userinfo WHERE vcUsername=?"; 
        $query = $this->db->query($sql, array($username));
        if ($query->num_rows() > 0) {
            return true;
        }
        return false;
    }
    /**
     *Validates if 2 given passwords, in plaintext are the same and are
     *above length 0
     *
     *@param string $password the initial password typed.
     *@param string $confirmPassword the second password typed by user.
     *@return string returns an empty string upon success.
     *@return string returns an error message upon failure.
     */
    public function passwordValidate($password,$confirmPassword=null){
        if(isset($confirmPassword))
            if($password != $confirmPassword)
                return 'Password mismatch user not updated! ';
        if(strlen($password) == 0){
            return 'Password must be greater than 0 characters. ';
        }
        return '';
    }
    
    /**
     *This function validates if a username is valid
     *@param string $username the name of the user
     *@return string returns an empty string on success on faliure it returns error message
     */
    public function validateUsername($username){
	if(strlen($username)== 0)
	    return "Cannot have empty username. ";
	/**
	 *@todo scrub username for invalid characters
	 */
	if(!ctype_alnum($username) ){
	    return "Username must be alphanumeric. ";
	}
	return '';
	
    }

    /**
     *This function gets the list of all KatManager users
     *
     *@return array Returns an array of all users of the kat manager.
     */
    public function getUserList(){
        $sql = "SELECT vcUsername, vcPassword, vcRealm, iUid FROM userinfo JOIN realms on userinfo.iRealm=realms.iRid"; //add realm restrictions?
        $query = $this->db->query($sql);
        return $query->result_array();
    }

    

}

?>